﻿using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
using Wazzup.Engine.Constants;
using Wazzup.Engine.Utility;

namespace Wazzup.Engine.Requests
{
    public static class WhatsAppRegister
    {
        public static async Task<bool> RegisterUser(string countryCode, string phoneNumber)
        {
            string website = "https://v.whatsapp.net/v2/code";
            string postData = GetRegString(countryCode, phoneNumber);
            string both = website + "?" + postData;

            var result = await StartWebRequest("", "", WhatsAppConstant.UserAgent, both);
            if (WhatsApp.DEBUG && result.Length > 0)
            {
                System.Diagnostics.Debug.WriteLine(result);
            }
            return result.Contains("status=\"success-sent\"");
        }

        public static async Task<bool> VerifyRegistration(string countryCode, string phoneNumber, string password, string code)
        {
            string tmpPassword = password.ToPassword();
            string verifyString = string.Format("https://v.whatsapp.net/v2/register?cc={0}&in={1}&id={2}&code={3}", new object[] { countryCode, phoneNumber, tmpPassword, code });

            var result = await StartWebRequest("", "", WhatsAppConstant.UserAgent, verifyString);
            System.Diagnostics.Debug.WriteLine(result);
            return true;
        }

        public static async Task<bool> ExistsAndDelete(string countrycode, string phone, string pass)
        {
            string webString = string.Format("https://v.whatsapp.net/v2/exist?cc={0}&in={1}", System.Uri.EscapeDataString(countrycode), System.Uri.EscapeDataString(phone));
            if (pass != null)
            {
                webString = webString + string.Format("&udid={0}", pass.ToPassword());
            }

            var result = await StartWebRequest("", "", WhatsAppConstant.UserAgent, webString);
            return result.Contains("status=\"ok\"");
        }

        private static async Task<string> StartWebRequest(string website, string postData, string userAgent, string both)
        {
           
            // = userAgent;
            try
            {
                //var response = (HttpWebResponse)await request.GetResponseAsync();
                //using (var reader = new StreamReader(response.GetResponseStream()))
                //{
                //    var html = reader.ReadToEnd();
                //    return html;
                //}
                var httpClient = new HttpClient();
                var url = new Uri(both);
                var httpRequestMessage = new HttpRequestMessage(HttpMethod.Get, url);
                httpRequestMessage.Headers.Add("User-Agent", userAgent);
                var response = await httpClient.SendAsync(httpRequestMessage);
                
                response.EnsureSuccessStatusCode();
                var res = await response.Content.ReadAsStringAsync();
                return res;
            }
            catch (WebException)
            {
                return "error";
            }
        }

        private static string MD5String(this string pass)
        {
            return EncryptionHelper.ComputeMd5(pass);
        }

        private static string ByteToString(byte[] dataMd5)
        {
            var sb = new StringBuilder();
            for (int i = 0; i < dataMd5.Length; i++)
                sb.AppendFormat("{0:x2}", dataMd5[i]);
            return sb.ToString();
        }

        private static string GetRegString(string countryCode, string phonenum, string codeType = "sms")
        {
            string tmpLangCode;
            string tmpLocalCode;
            GetLangAndLocale(CultureInfo.CurrentCulture, out tmpLangCode, out tmpLocalCode);
            if (tmpLocalCode == "029")
            {
                tmpLocalCode = "US";
            }
            string phoneNumber = phonenum;
            const string buildHash = WhatsAppConstant.WhatsBuildHash;
            string tmpToken = ("889d4f44e479e6c38b4a834c6d8417815f999abe" + buildHash + phoneNumber).MD5String().ToLower();
            string regString = string.Format("cc={0}&in={1}&lg={2}&lc={3}&method={4}&mcc=000&mnc=000&imsi=000&token={5}&id={6}", new object[] { countryCode, phoneNumber, tmpLangCode, tmpLocalCode, codeType, tmpToken,MD5String(phoneNumber) });
            return regString;
        }

        private static string ToPassword(this string bs)
        {
            if (bs.Contains(":"))
            {
                string ps = bs.ToUpper();
                string ls = ps + ps;
                return ls.MD5String();
            }
            else
            {
                return (new string(Reverse(bs).ToCharArray()).MD5String());
            }
        }
        public static string Reverse(string text)
        {
            char[] cArray = text.ToCharArray();
            string reverse = String.Empty;
            for (int i = cArray.Length - 1; i > -1; i--)
            {
                reverse += cArray[i];
            }
            return reverse;
        }
        private static void GetLangAndLocale(CultureInfo that, out string lang, out string locale)
        {
            string name = that.Name;
            int index = name.IndexOf('-');
            if (index > 0)
            {
                int num2 = name.LastIndexOf('-');
                lang = name.Substring(0, index);
                locale = name.Substring(num2 + 1);
            }
            else
            {
                lang = name;
                switch (lang)
                {
                    case "cs":
                        locale = "CZ";
                        return;

                    case "da":
                        locale = "DK";
                        return;

                    case "el":
                        locale = "GR";
                        return;

                    case "ja":
                        locale = "JP";
                        return;

                    case "ko":
                        locale = "KR";
                        return;

                    case "sv":
                        locale = "SE";
                        return;

                    case "sr":
                        locale = "RS";
                        return;
                }
                locale = lang.ToUpper();
            }
        }

    }
}
